<!--
https://web1.capetown.gov.za/web1/opendataportal/AllDatasets
https://web1.capetown.gov.za/web1/opendataportal/DatasetDetail?DatasetName=Taxi%20routes
https://web1.capetown.gov.za/web1/opendataportal/DatasetDetail?DatasetName=Building%20footprints
-->
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Taxi routes in capetown - ECHARTS-GL</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes"> <!-- Fullscreen Landscape on iOS -->
    <link rel="stylesheet" href="./common.css">
</head>
<body>
<div id="main"></div>
<script src="../node_modules/echarts/dist/echarts.js"></script>
<script src="../dist/echarts-gl.js"></script>
<script src='lib/mapbox-gl.js'></script>
<link href='lib/mapbox-gl.css' rel='stylesheet'/>
<script src="https://unpkg.com/shapefile@0.6"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/dat.gui.js"></script>
<script src="js/commonUI.js"></script>
<script>
    mapboxgl.accessToken = window.location.search.slice(1);
    var chart = echarts.init(document.getElementById('main'));

    var ENCODE_SCALE = 1e6;

    function decodeLine(line) {

        var result = [];
        var prevX = line[0];
        var prevY = line[1];

        for (var i = 0; i < line[2].length; i += 2) {
            var x = line[2].charCodeAt(i) - 64;
            var y = line[2].charCodeAt(i + 1) - 64;
            // ZigZag decoding
            x = (x >> 1) ^ (-(x & 1));
            y = (y >> 1) ^ (-(y & 1));
            // Delta deocding
            x += prevX;
            y += prevY;

            prevX = x;
            prevY = y;
            // Dequantize
            result.push([x / ENCODE_SCALE, y / ENCODE_SCALE]);
        }

        return result;
    }

    var geoJSON = {
        features: []
    };
    var regions = [];
    var readShp = new Promise(function (resolve, reject) {
        shapefile.open('data/buildings-capetown.shp', 'data/buildings-capetown.dbf')
            .then(source => source.read()
                .then(function append(result) {
                    if (result.done) {
                        resolve();
                        return;
                    }
                    var feature = result.value;
                    feature.properties.name = geoJSON.features.length + '';
                    regions.push({
                        name: geoJSON.features.length + '',
                        value: 1,
                        height: feature.properties.SHAPE_leng * 10000
                    })
                    geoJSON.features.push(feature);
                    return source.read().then(append);
                })
            );
    });

    Promise.all([$.getJSON('data/taxi-routes-capetown.json'), readShp])
        .then(function ([data, lastFeature]) {

            var lines = data.map(function (track) {
                return {
                    coords: decodeLine(track)
                };
            });

            echarts.registerMap('buildings', geoJSON);

            console.profile('setOption');
            chart.setOption({
                mapbox3D: {
                    center: [18.424552361777955, -33.92188144682616],
                    zoom: 14,
                    pitch: 50,
                    bearing: -10,
                    altitudeScale: 2,
                    style: 'mapbox://styles/mapbox/dark-v9',
                    postEffect: {
                        enable: true,
                        screenSpaceAmbientOcclusion: {
                            enable: true,
                            intensity: 1.2,
                            radius: 6,
                            quality: 'high'
                        },
                        screenSpaceReflection: {
                            enable: true
                        },
                        depthOfField: {
                            enable: false,
                            focalDistance: 80,
                            blurRadius: 5
                        }
                    },
                    light: {
                        main: {
                            intensity: 1,
                            shadow: true,
                            shadowQuality: 'high'
                        },
                        ambient: {
                            intensity: 0.
                        },
                        ambientCubemap: {
                            texture: 'asset/pisa.hdr',
                            exposure: 2,
                            diffuseIntensity: 1,
                            specularIntensity: 2
                        }
                    }
                },
                series: [{
                    type: 'lines3D',

                    coordinateSystem: 'mapbox3D',

                    effect: {
                        show: true,
                        constantSpeed: 5,
                        trailWidth: 2,
                        trailLength: 0.8,
                        trailOpacity: 1,
                        spotIntensity: 10
                    },

                    blendMode: 'lighter',

                    polyline: true,

                    lineStyle: {
                        width: 0.1,
                        color: 'rgb(200, 40, 0)',
                        opacity: 0.
                    },

                    data: {
                        count: function () {
                            return lines.length;
                        },
                        getItem: function (idx) {
                            return lines[idx]
                        }
                    }
                }, {
                    type: 'map3D',
                    map: 'buildings',

                    coordinateSystem: 'mapbox3D',
                    shading: 'realistic',
                    silent: true,

                    data: regions,

                    itemStyle: {
                        color: '#444'
                    },

                    realisticMaterial: {
                        metalness: 1,
                        roughness: 0.2,
                    }
                }]
            });

            console.profileEnd('setOption');
        });

    window.addEventListener('keydown', function () {
        chart.dispatchAction({
            type: 'lines3DToggleEffect',
            seriesIndex: 0
        });
    });

    window.addEventListener('resize', function () {
        chart.resize();
    });

    var gui = new dat.GUI();
    var config = {
        color: 'rgb(200, 40, 0)'
    };
    gui.addColor(config, 'color').onFinishChange(function () {
        chart.setOption({
            series: [{
                lineStyle: {
                    color: config.color
                }
            }]
        });
    })

</script>
</body>
</html>
